package rs;

import java.util.*;
import java.io.*;

public class Proxy implements Serializable {

	private Hashtable<String, Integer> vezes;
	
	private Hashtable<String,Vector<Cacheable>> resultados;
	
	private final int MAX_ENTRIES = 5;
	
	public Proxy() {
		vezes = new Hashtable();
		resultados = new Hashtable();
	}

	public Vector getResult(int start, int end, String query) {
		
		Vector v = getResult(query);
		Vector new_ = new Vector();
		
		if (v != null) {
			
			for (int i=0; i<v.size(); i++) {
				if (i>= start && i<= end)
					new_.add(v.get(i));
			}
			
			return new_;
			
		}
		
		return v;
	}
	
	public Vector getResult(String query){
		if (resultados.containsKey(query))
			return resultados.get(query);
		else
			return null;
	}
	
	public void addResult(String query, Vector result) {
		
		incrementVezes(query);
		
		if (resultados.containsKey(query)) {
			resultados.put(query, result);			
		} else {
			//Ver se vale a pena por na tabela de resultados
			int v = vezes.get(query);
			int numMaiores=0;
			String s="";
			
			for (Enumeration<String> e=resultados.keys(); e.hasMoreElements();) {
				s=e.nextElement();
				
				if (vezes.get(s) >= v) {
					numMaiores++;
				}
			}
			
			if (query.equals("d"))
				System.out.println("existem " + numMaiores + " numMaiores");
			
			if (numMaiores < MAX_ENTRIES) {
				resultados.put(query, result);
				
				//Se vamos ter que mandar um embora
				if (resultados.values().size() > MAX_ENTRIES) {
					
					String query_a_ir="";
					int vezes_da_query_a_ir=v;

					for (Enumeration<String> e=vezes.keys(); e.hasMoreElements(); ) {
						s=e.nextElement();
						if (vezes.get(s) < vezes_da_query_a_ir) {
							query_a_ir = s;
							vezes_da_query_a_ir = vezes.get(s);
						}
					}
					
					resultados.remove(query_a_ir);
					
				}
			}
		}
	}
	
	private void incrementVezes(String query) {
		int a=0;
		
		if (vezes.containsKey(query))
			a= vezes.get(query);
			
		vezes.put(query, a+1);
	}
	
	public String toString() {
		String ss = "";
		
		if (resultados.values().size() > 0)
			ss = "Proxy contem as seguintes querys:\n";
		else return "Proxy Nao contem querys";
		
		String s="";
		
		for (Enumeration<String> e=resultados.keys(); e.hasMoreElements();) {
			s=e.nextElement();
			ss+="Query=" + s + ";vezes=" + vezes.get(s) + "; resultados=[";
			Vector res = resultados.get(s);
			
			for (int i=0; i<res.size(); i++)
				ss += res.get(i) + ";;";

			ss+="]\n";

		}

		return ss;
	}
	
	public void update(Cacheable cacheable, boolean remove) {
		
		//Percorrer os resultados a ver se existem elementos afectados
		for (Enumeration<String> e=resultados.keys(); e.hasMoreElements();) {
			Vector<Cacheable> results;
			
			results = resultados.get(e.nextElement());
			
			for (int i=0; i<results.size(); i++) {
				Cacheable c = results.get(i);
				
				if (c.getCacheCode().equals(cacheable.getCacheCode())) {
					results.remove(c);
					
					//Se for para fazer edit em vez de update
					if (!remove)
						results.add(cacheable);
				}
			}
		}
	}
		
	public void clearCache() {
		resultados = new Hashtable();
		
	}
	
	public Vector<Cacheable> getResults(String query) {
		incrementVezes(query);
		return resultados.get(query);
	}
}
